package com.theyeasy.dvmini.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

/**
 * Created by SYSTEM on 2017/3/27.
 */
public class CommonUtil {


	protected final Logger log = LoggerFactory.getLogger(this.getClass());

	private final static String WEIXIN_URL = "http://120.76.74.61:9090";

	/**
	 * 获取系统默认时间
	 * 
	 * @return
	 */
	public static Timestamp getTime() {
		return new Timestamp(new Date().getTime());
	}

	/**
	 * 在默认时间上添加多少天
	 * 
	 * @Description (TODO这里用一句话描述这个方法的作用)
	 * @param date
	 *            天数
	 * @return
	 */
	public static Date addTime(Date date, int day) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, day);// 把日期往后增加一天.整数往后推,负数往前移动
		date = calendar.getTime();
		return date;
	}

	public final static String getIp(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("Proxy-Client-IP");
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("WL-Proxy-Client-IP");
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("HTTP_CLIENT_IP");
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("HTTP_X_FORWARDED_FOR");
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getRemoteAddr();
			}
		} else if (ip.length() > 15) {
			String[] ips = ip.split(",");
			for (int index = 0; index < ips.length; index++) {
				String strIp = (String) ips[index];
				if (!("unknown".equalsIgnoreCase(strIp))) {
					ip = strIp;
					break;
				}
			}
		}
		return ip;
	}

	/**
	 * 按格式返回日期字符串
	 * 
	 * @Description (TODO这里用一句话描述这个方法的作用)
	 * @param date
	 * @param format
	 * @return
	 */
	public static String getDateFormat(Date date, String format) {
		SimpleDateFormat dateFormater = new SimpleDateFormat(format);
		return dateFormater.format(date);
	}

	/**
	 * 返回json格式
	 * 
	 * @param cla
	 * @return
	 */
	public static <T> String getJson(T cla) {

		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
		if (cla == null)
			return "";

		return gson.toJson(cla);

	}

	/**
	 * 返回json格式
	 * 
	 * @param cla
	 * @return
	 */
	public static String getSimpleDateFormat(Date date) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return df.format(date);
	}

	public static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	public static String JsonToObject(String result) {
		Gson gson = new Gson();
		Map<String, Object> resultMap = gson.fromJson(result, new TypeToken<Map<String, Object>>() {
		}.getType());
		String str = "{";
		for (Iterator<String> it = resultMap.keySet().iterator(); it.hasNext();) {
			String key = it.next();
			if (resultMap.get(key) != null && !resultMap.get(key).equals("")) {
				str += "\"" + key + "\":\"" + resultMap.get(key) + "\",";
			}
		}
		String newJson = str.substring(0, str.length() - 1) + "}";
		return newJson;
	}

	public static void download(String urlString, String filename, String savePath) throws Exception {
		// 构造URL
		URL url = new URL(urlString);
		// 打开连接
		URLConnection con = url.openConnection();
		// 设置请求超时为5s
		con.setConnectTimeout(5 * 1000);
		// 输入流
		InputStream is = con.getInputStream();

		// 1K的数据缓冲
		byte[] bs = new byte[1024];
		// 读取到的数据长度
		int len;
		// 输出的文件流
		File sf = new File(savePath);
		if (!sf.exists()) {
			sf.mkdirs();
		}
		OutputStream os = new FileOutputStream(sf.getPath() + "/" + filename);
		// 开始读取
		while ((len = is.read(bs)) != -1) {
			os.write(bs, 0, len);
		}
		// 完毕，关闭所有链接
		os.close();
		is.close();
	}

	/**
	 * 向指定 URL 发送POST方法的请求
	 * 
	 * @param url
	 *            发送请求的 URL
	 * @param param
	 *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
	 * @return 所代表远程资源的响应结果
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			//conn.setRequestProperty("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
			conn.setRequestProperty("content-type", "application/json");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setRequestProperty("Charset", "UTF-8");
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
			// 发送请求参数
			System.out.println(param);
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		System.out.println(result);
		return result;
	}

	public static String sendGet(String url, String param)

	{
		String result = "";
		BufferedReader in = null;
		try {
			String urlNameString = "";
			if (param==null || param.equals("")) {
				urlNameString = url;
			} else if (!url.contains("?")) {
				urlNameString = url + "?" + param;
			} else {
				urlNameString = url + "&" + param;
			}
			System.out.println(urlNameString);
			URL realUrl = new URL(urlNameString);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setRequestProperty("Accept-Charset", "utf-8");
			conn.setRequestProperty("Charset", "utf-8");
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			// 建立实际的连接
			conn.connect();
			// 定义 BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return result;
	}

	 
	 
	/**
	 * 传入data反序列化对象
	 * 
	 * @param <T>
	 * @param <T>
	 * @param data
	 * @return 返回对象日期格式为yyyy-MM-dd HH:mm:ss
	 * @throws Exception
	 */
	public static <T> T getEntity(Object data, Class<T> cla) {
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
		String json = "";
		if (data instanceof String) {
			json = data.toString();
		} else {
			json = gson.toJson(data);
		}
		try {
			// json=json.replace("\\", "");
			// json=json.replace("/", "");
			return gson.fromJson(json, cla);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 传入data反序列化对象
	 * 
	 * @param <T>
	 * @param <T>
	 * @param data
	 * @return 返回对象日期格式为yyyy-MM-dd HH:mm:ss
	 * @throws Exception
	 */
	public static <T> T getEntity(Object data, Type cla) {
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
		String json = "";
		if (data instanceof String) {
			json = data.toString();
		} else {
			json = gson.toJson(data);
		}
		try {
			// json=json.replace("\\", "");
			// json=json.replace("/", "");
			return gson.fromJson(json, cla);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 传入data反序列化对象
	 * 
	 * @param <T>
	 * @param <T>
	 * @param data
	 * @return 返回对象日期格式为yyyy-MM-dd HH:mm:ss
	 * @throws Exception
	 */
	public static <T> T getNewEntity(Object data, Class<T> cla) {
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm").create();
		String json = "";
		if (data instanceof String) {
			json = data.toString();
		} else {
			json = gson.toJson(data);
		}
		try {
			// json=json.replace("\\", "");
			// json=json.replace("/", "");
			return gson.fromJson(json, cla);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 修改字符串中的unicode码
	 * 
	 * @param s
	 *            源str
	 * @return 修改后的str
	 */
	public static String decode2(String s) {
		StringBuilder sb = new StringBuilder(s.length());
		char[] chars = s.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			char c = chars[i];
			if (c == '\\' && chars[i + 1] == 'u') {
				char cc = 0;
				for (int j = 0; j < 4; j++) {
					char ch = Character.toLowerCase(chars[i + 2 + j]);
					if ('0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f') {
						cc |= (Character.digit(ch, 16) << (3 - j) * 4);
					} else {
						cc = 0;
						break;
					}
				}
				if (cc > 0) {
					i += 5;
					sb.append(cc);
					continue;
				}
			}
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * 发送短信, type类别 1调用微易科技网发送验证码
	 */
	public static String SendSms(int type, String phone) {
		/*
		 * Gson gson = new Gson(); ApiParam apiParam = new ApiParam(); Sms sms =
		 * new Sms(); sms.setPhone(phone); sms.setContent("");
		 * sms.setTempletid(1); // 短信验证码模板 apiParam = getParam(106,
		 * "Sms_SendCheckCode", sms, phone, "vankehouse"); String json =
		 * gson.toJson(apiParam); String result =
		 * SystemUtil.sendPost("http://m.theyeasy.com/Api/AcceptCmd", json);
		 * ResultMsg msg = gson.fromJson(result, ResultMsg.class); if (msg !=
		 * null) { return msg.getMsg(); }
		 */
		return "";
	}

	/**
	 * 发送短信, type类别 1调用微易科技网发送验证码
	 */
	public static String SendRechargeSms(int type, String phone) {
		/*
		 * Gson gson = new Gson(); ApiParam apiParam = new ApiParam(); Sms sms =
		 * new Sms(); sms.setPhone(phone); sms.setContent("");
		 * sms.setTempletid(type); // 短信验证码模板 apiParam = getParam(106,
		 * "Sms_SendCheckCode", sms, phone, "vankehouse"); String json =
		 * gson.toJson(apiParam); String result =
		 * SystemUtil.sendPost("http://m.theyeasy.com/Api/AcceptCmd", json);
		 * System.out.println(result); ResultMsg msg = gson.fromJson(result,
		 * ResultMsg.class); if (msg != null) { return msg.getMsg(); }
		 */
		return null;
	}

	/**
	 * 验证短信验证码
	 */
	public static String checkSendSms(String phone, String code) {
		/*
		 * Gson gson = new Gson(); ApiParam apiParam = new ApiParam(); Sms sms =
		 * new Sms(); sms.setPhone(phone); sms.setContent(code);
		 * sms.setTempletid(1); // 短信验证码模板 apiParam = getParam(106,
		 * "Sms_CheckCode", sms, phone, "vankehouse"); String json =
		 * gson.toJson(apiParam); String result =
		 * SystemUtil.sendPost("http://m.theyeasy.com/Api/AcceptCmd", json);
		 * ResultMsg msg = gson.fromJson(result, ResultMsg.class); if (msg !=
		 * null) { if (msg.getCode() != null && msg.getCode() == 0) { return
		 * "ok"; } else { return msg.getMsg(); } }
		 */
		return "";
	}

	/*
	 * public static ApiParam getParam(Integer appid, String sendName, Object
	 * data, String nonce, String token) { ApiParam apiParam = new ApiParam();
	 * Gson gson = new Gson(); // apiComm String timestamp =
	 * System.currentTimeMillis() / 1000 + ""; String headerStr =
	 * SystemUtil.getHeader(timestamp, nonce, "132145xXXdasd23", token, appid);
	 * Header header = gson.fromJson(headerStr, Header.class); Cmd newCmd = new
	 * Cmd(); newCmd.setName(sendName); apiParam.setData(data);
	 * apiParam.setCmd(newCmd); apiParam.setHeader(header); return apiParam; }
	 */

	public static List<String> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		List<String> lDate = new ArrayList();
		lDate.add(df.format(beginDate));// 把开始时间加入集合
		Calendar cal = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		cal.setTime(beginDate);

		boolean bContinue = true;
		while (bContinue) {
			// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
			cal.add(Calendar.MINUTE, 60);// 每次增加五分钟
			// 判断此日期是否在指定日期之后
			if (endDate.after(cal.getTime())) {
				String t = df.format(cal.getTime());
				lDate.add(t);
			} else {
				break;
			}
		}
		lDate.add(df.format(endDate));// 把结束时间加入集合
		return lDate;
	}

	// 当天一天每隔5分钟的时间
	public static List<Date> test1(Date date) {
		Date start = dayStartDate(date);// 转换为天的起始date
		Date nextDayDate = nextDay(start);// 下一天的date

		List<Date> result = new ArrayList<Date>();
		while (start.compareTo(nextDayDate) < 0) {
			result.add(start);
			// 日期加5分钟
			start = addFiveMin(start, 5);
		}

		return result;
	}

	public static Date nextDay(Date start) {
		Calendar c = Calendar.getInstance();
		c.setTime(start);
		c.add(Calendar.DATE, 1);
		return c.getTime();
	}

	public static Date dayStartDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime((Date) date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		return c.getTime();
	}

	// 日期段的一小时间隔时间
	public static List<Date> test(Date startDate, Date endDate) {

		List<Date> result = new ArrayList<Date>();
		while (startDate.compareTo(endDate) < 0) { // 判断开始于结束时期
			result.add(startDate);
			startDate = addFiveMin(startDate, 60); // 日期加60分钟
		}

		return result;
	}

	public static Date addFiveMin(Date start, int offset) {
		Calendar c = Calendar.getInstance();
		c.setTime(start);
		c.add(Calendar.MINUTE, offset);
		return c.getTime();
	}

	public static Date addone(Date d) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(d);
		calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
		d = calendar.getTime(); // 这个时间就是日期往后推一天的结果
		return d;
	}

	public static Date removeSeven(Date d) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(d);
		calendar.add(calendar.DATE, -7);// 把日期往后增加一天.整数往后推,负数往前移动
		d = calendar.getTime(); // 这个时间就是日期往后推一天的结果
		return d;
	}

	public static void main(String[] args) {

	}

	public static void sendWeiXinTicket(String appId, String ticket) {

		String url = WEIXIN_URL + "/common/" + appId + "/ticket";

		String value = ticket;
		try {

			value = URLEncoder.encode(value, "utf-8");

			String param = "ticket=" + value;

			String result = CommonUtil.sendGet(url, param);
			System.out.println("执行微信ticket更新-----" + result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void authorizerInsert(String openAppId, String appId, String refreshToken) {
		String url = WEIXIN_URL + "/authorizer/" + openAppId + "/" + appId + "/insert";
		
		if(refreshToken==null || refreshToken.length()<1)
		{
			System.out.println("执行微信authorizerInsert更新--openAppId=" + openAppId + ",appId=" + appId + "--refreshToken="
					+ refreshToken + "-----, refreshToken为空，中断更新token托管平台上的记录!");
			return;
		}
		String value = refreshToken;
		try {

			value = URLEncoder.encode(value, "utf-8");

			String param = "refreshToken=" + value;

			String result = CommonUtil.sendGet(url, param);
			System.out.println("执行微信authorizerInsert更新--openAppId=" + openAppId + ",appId=" + appId + "--refreshToken="
					+ refreshToken + "-----" + result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 第三方平台
	 * 
	 * @param openAppId
	 * @param appId
	 * @param refreshToken
	 */
	public static void commonInsert(String openAppId, String openNamem, String openAppSecret, String openToken,
			String openAesKey) {

		String url = WEIXIN_URL + "/common/" + openAppId + "/insert";
		// @RequestParam String openName,@RequestParam String
		// openAppId,@RequestParam String openAppSecret,@RequestParam
		// String openToken,@RequestParam String openAesKey
		try {

			openNamem = URLEncoder.encode(openNamem, "utf-8");
			openAppSecret = URLEncoder.encode(openAppSecret, "utf-8");
			openToken = URLEncoder.encode(openToken, "utf-8");
			openAesKey = URLEncoder.encode(openAesKey, "utf-8");

			String param = "openName=" + openNamem + "&openAppSecret=" + openAppSecret + "&openToken=" + openToken
					+ "&openAesKey=" + openAesKey;

			String result = CommonUtil.sendGet(url, param);
			System.out.println("执行微信commonInsertt更新-----" + result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 取消授权
	 * 
	 * @param openAppId
	 * @param appId
	 * @param refreshToken
	 */
	public static void cancelAuthorization(String openAppId, String appId) {
		try {
			String url = WEIXIN_URL + "/cancelAuthorization/" + openAppId + "/" + appId;
			String result = CommonUtil.sendGet(url, null);
			System.out.println("执行微信cancelAuthorization更新-----" + result);
		} catch (Exception e) {
			// TODO: handle exception

		}
	}
}

class ResultMsg {

	private Integer code;
	private String msg;

	public Integer getCode() {
		return code;
	}

	public void setCode(Integer code) {
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

}

class Sms {

	private String phone;
	private String content;
	private int templetid;

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public int getTempletid() {
		return templetid;
	}

	public void setTempletid(int templetid) {
		this.templetid = templetid;
	}

}
